

var isPlainObject = require('lodash/isPlainObject')


var ActionTypes = {
    INIT: '@@redux/INIT'
}

module.exports = function createStore(reducer, preloadedState, enhancer) {

    var currentReducer   = reducer           //把 reducer 赋值给 currentReducer
    var currentState     = preloadedState    //把 preloadedState 赋值给 currentState
    var currentListeners = []                //初始化 listeners 数组
    var nextListeners    = currentListeners  //nextListeners 和 currentListeners 指向同一个引用
    var isDispatching    = false             //标记正在进行dispatch


    //判断 preloadedState 是一个函数并且 enhancer 是未定义 
    if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
        enhancer = preloadedState  // 把 preloadedState 赋值给 enhancer
        preloadedState = undefined // 把 preloadedState 赋值为 undefined
    }

    //判断 enhancer 不是 undefined
    if (typeof enhancer !== 'undefined') {
        //调用 enhancer ,返回一个新强化过的 store creator
        return enhancer(createStore)(reducer, preloadedState)
    }

    // 确保 nextListeners 和 currentListeners 内存引用不一样
    function ensureCanMutateNextListeners() {
        if (nextListeners === currentListeners) {
            nextListeners = [...currentListeners]
        }
    }
    // 添加监听函数
    function subscribe(listener) {

        if (typeof listener !== 'function') {
            throw new Error('Expected listener to be a function.')
        }
        var isSubscribed = true

        ensureCanMutateNextListeners()
        nextListeners.push(listener)
        

        return function unsubscribe() {
            if (!isSubscribed) {

                return
            }
            isSubscribed = false
            ensureCanMutateNextListeners()
            var index = nextListeners.indexOf(listener)
            nextListeners.splice(index, 1)
        }
    }
    // 修改 state
    function dispatch(action) {
        //判断 action 不是普通对象。也就是说该对象由 Object 构造函数创建
        if (!isPlainObject(action)) {

            //抛出一个异常(actions 必须是一个普通对象. 或者用自定义的中间件来处理异步 actions)
            throw new Error(
                'Actions must be plain objects. ' +
                'Use custom middleware for async actions.'
            )
        }
        // 判断 action 对象的 type 属性等于 undefined 
        if (typeof action.type === 'undefined') {
            //抛出一个异常
            throw new Error(
                'Actions may not have an undefined "type" property. ' +
                'Have you misspelled a constant?'
            )
        }
        //判断 dispahch 正在运行，Reducer在处理的时候又要执行 dispatch
        if (isDispatching) {
            //抛出一个异常(Reducer在处理的时候不能 dispatch action)
            throw new Error('Reducers may not dispatch actions.')
        }

        try {
            //标记 dispatch 正在运行
            isDispatching = true

            //执行当前 Reducer 函数返回新的 state
            currentState = currentReducer(currentState, action)

        } finally { // (try catch) 最终会被执行的地方

            //标记 dispatch 没有在运行 
            isDispatching = false
        }

        //所有的的监听函数赋值给 listeners
        var listeners = currentListeners = nextListeners

        //遍历所有的监听函数
        for (var i = 0; i < listeners.length; i++) {

            // 执行每一个监听函数
            listeners[i]()
        }

        //返回传入的 action 对象
        return action
    }
    // 获取 state
    function getState() {
        //当前的state tree
        return currentState
    }

    dispatch({ type: ActionTypes.INIT })

    //返回 store 暴漏出的api
    return {
        subscribe,
        dispatch,
        getState,
    }
}